#ifndef __STD_TYPE_H__
#define __STD_TYPE_H__

#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif


/// 标准错误码
typedef int os_err_t;
#define OS_OK                     0    /*!< esp_err_t value indicating success (no error) */
#define OS_FAIL                  -1    /*!< Generic esp_err_t code indicating failure */
#define OS_ERR_NO_MEM            -2    /*!< Out of memory */
#define OS_ERR_INVALID_ARG       -3    /*!< Invalid argument */
#define OS_ERR_INVALID_STATE     -4    /*!< Invalid state */
#define OS_ERR_INVALID_SIZE      -5    /*!< Invalid size */
#define OS_ERR_NOT_FOUND         -6    /*!< Requested resource not found */
#define OS_ERR_NOT_SUPPORTED     -7    /*!< Operation or feature not supported */
#define OS_ERR_TIMEOUT           -8    /*!< Operation timed out */
#define OS_ERR_INVALID_RESPONSE  -9    /*!< Received response was invalid */
#define OS_ERR_INVALID_CRC       -10   /*!< CRC or checksum was invalid */
#define OS_ERR_INVALID_VERSION   -11   /*!< Version was invalid */
#define OS_ERR_INVALID_MAC       -12   /*!< MAC address was invalid */
#define OS_ERR_INVALID_IF_TYPE   -13   /*!< Interface type was invalid */
#define OS_ERR_INVALID_SRC_ADDR  -14   /*!< Source address was invalid */
#define OS_ERR_INVALID_DST_ADDR  -15   /*!< Destination address was invalid */
#define OS_ERR_INVALID_FRAME_LEN -16   /*!< Invalid frame length */
#define OS_ERR_INVALID_PARAM_LEN -17   /*!< Invalid parameter length */
#define OS_ERR_BUFFER_OVERFLOW   -18   /*!< Buffer overflow */
#define OS_ERR_BUFFER_UNDERFLOW  -19   /*!< Buffer underflow */
#define OS_ERR_INVALID_COMMAND   -20   /*!< Invalid command */


typedef uint64_t u64;
typedef uint32_t uint32_t;
typedef uint16_t uint16_t;
typedef uint8_t  uint8_t;

typedef uint64_t uint64;
typedef uint32_t uint32;
typedef uint16_t uint16;
typedef uint8_t  uint8;

typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t  s8;


//typedef int bool;
//#define true  1
//#define false (!true)

typedef int bool;
#define TRUE  1
#define FALSE (!TRUE)

#define RESET   (0)
#define SET     (!RESET)

#define OFF 	(0)
#define ON  	(1)
#define REVERSE (2)
#define TOGGLE  REVERSE
#define BLINK   (3)

#define UP		(0)
#define DOWN	(1)

#define INPUT			(0)		///< 输入
#define OUTPUT			(1)		///< 输出
#define HI_IMPEDANCE 	(0xFF)	///< 高阻

#define MAXU32 	((uint32_t)0xFFFFFFFF)
#define MAXU16	((uint16_t)0xFFFF)
//#define MAXINT  32767


/// 电平跳变边沿方向
typedef enum {
	EDGE_ANY 	= -1,       ///< 任意
	EDGE_DOWN 	= 0,        ///< 下降沿,电平由高到低跳变
	EDGE_UP		= 1       	///< 上升沿,电平由低到高跳变
} EdgeType;

/// 电平
typedef enum {
	LEVEL_ANY	= -1,       ///< 任意
	LEVEL_LOW	= 0,        ///< 低电平
	LEVEL_HIGH	= 1       	///< 高电平
} LevelType;

// 开关状态
typedef enum {
	SWITCH_STATE_OFF        = 0x00,
	SWITCH_STATE_ON         = 0x01,
	SWITCH_STATE_REVERSE    = 0x02,
	SWITCH_STATE_TOGGLE     = SWITCH_STATE_REVERSE,
	SWITCH_STATE_BLINK      = 0x03,
	SWITCH_STATE_MAX		= 0xFF
} SwitchState;

// 开关上电状态恢复方式
typedef enum {
	STATE_MEMORY_OFF        = 0x00, // 关
	STATE_MEMORY_ON         = 0x01, // 开
	STATE_MEMORY_KEEP       = 0x02, // 掉电前状态
	STATE_MEMORY_REVERSE    = 0x03, // 掉电前状态取反
	STATE_MEMORY_NOP        = 0xFF  // 不管它
} SwitchStateMemory;

// 按钮状态
typedef enum {
	BUTTON_UP        	= 0x00,
	BUTTON_DOWN        	= 0x01,
	BUTTON_CLICK      	= 0x02,
	BUTTON_LONG_PRESS1 	= 0x03,
	BUTTON_LONG_PRESS2 	= 0x04
} ButtonState;

/// 操作结果
typedef enum enOpResult {
	OPR_NOP = 0,
	OPR_Pending = 127,
	OPR_TimeoutTotal = -2,
	OPR_TimeoutInterval = -3,
	OPR_OK = 1,
	OPR_Failed = 2,
	OPR_WantedBytesLengthReceived = 3,
	OPR_InternalError = 4
} OpResult;

/// Rx 工作模式
typedef enum {
    ShipCommRxWorkMode_SyncIo = 0,         ///< 同步IO模式
    ShipCommRxWorkMode_AsyncIo,            ///< 异步IO模式
    ShipCommRxWorkMode_Bridge,             ///< 桥接模式
    ShipCommRxWorkMode_CommandResponse,    ///< “命令<->响应”模式
    ShipCommRxWorkMode_CommandMonitor,     ///< 命令行服务模式
    ShipCommRxWorkMode_FrameMonitor,       ///< 帧监听模式
} ShipCommRxWorkMode;


/// 时间
typedef struct {
	uint8_t hour;
	uint8_t minute;
	uint8_t second;
} Time;

/// 时间段
typedef struct {
	Time start;
	Time end;
} TimePeriod;

/// 日期
typedef struct {
	uint16_t year;
	uint8_t month;
	uint8_t day;
	uint8_t weekday;
} Date;

/// 日期&时间
typedef struct {
	Date date;
	Time time;
} DateTime;

typedef union {
	uint32_t dw;
	struct {
		uint8_t majorVersion;  ///< 主版本号
		uint8_t minorVersion;  ///< 小版本号
		uint16_t buildNumber;  ///< Build Number
	} st;
} Version;

/// uint16_t 字节序颠倒
#define BL16(w)  		((((w)&0x00FF)<<8) | (((w)&0xFF00)>>8))
/// uint32_t 字节序颠倒
#define BL32(dw) 		((((dw)&0x000000FF)<<24) | (((dw)&0x0000FF00)<<8) | (((dw)&0x00FF0000)>>8) | (((dw)&0xFF000000)>>24))
/// 第 n 位的掩码
#define BV(n) 			(1U<<(n))
/// 取 v 的第 n 位的值
#define BITx(v, n)		(((v) >> (n)) & 1)
/// 取一个字节数组的第 n 位的值
#define BITn(buff, n)	BITx((buff)[(n)>>3], (n)&7)
/// 设置 v 的第 n 位为 1
#define BitSet(v, n)	((v) |= BV(n))
/// 设置 v 的第 n 位为 0
#define BitReset(v, n)	((v) &= ~BV(n))
/// 把 v 的第 n 位取反
#define BitInvert(v, n)	((v) ^= BV(n))

/// 取字节的高 4 位
#define HI4B(b)   (((b)&0xF0) >>4)
/// 取字节的低 4 位
#define LO4B(b)   ((b)&0x0F)

/// 取 uint16_t 的高字节
#define HIBYTE(w)   (((w)&0xFF00) >>8)
/// 取 uint16_t 的低字节
#define LOBYTE(w)   ((w)&0x00FF)

/// 取 uint32_t 的高 uint16_t
#define HIWORD(dw)  (((dw)&0xFFFF0000)>>16)
/// 取 uint32_t 的低 uint16_t
#define LOWORD(dw)  ((dw)&0x0000FFFF)

/// 取 uint32_t 的第 1 字节(大端在前)
#define BHH(dw) HIBYTE(HIWORD(dw))
/// 取 uint32_t 的第 2 字节(大端在前)
#define BHL(dw) LOBYTE(HIWORD(dw))
/// 取 uint32_t 的第 3 字节(大端在前)
#define BLH(dw) HIBYTE(LOWORD(dw))
/// 取 uint32_t 的第 4 字节(大端在前)
#define BLL(dw) LOBYTE(LOWORD(dw))

#define MAKE_BYTE(H4B, L4B)				((uint8_t)((((H4B)<<4)&0xF0) | ((L4B)&0x0F)))
#define MAKE_WORD(BH, BL)               ((uint16_t)((((BH)&0xFF)<<8) | ((BL)&0xFF)))
#define MAKE_DWORD(BHH, BHL, BLH, BLL)  ((uint32_t)((MAKE_WORD((BHH), (BHL))<<16) | MAKE_WORD((BLH), (BLL))))

/// 生成一个表示日期的16位数据：年:7-月:4-日:5，表示 2000/1/1 ~ 2127/12/31 之间的所有日期
#define MAKE_DATE16(y, m, d)            ((uint16_t)((((y)%1000)<<9) | ((m)<<5) | (d)))

/// 生成版本号字符串
#define MAKE_VERSION_STRING(major, minor, build)  (QUOTE(major) "." QUOTE(minor) "." QUOTE(build))

/// 绝对值
#define ABS(num) (((num)>=0)?(num):(-num))
/// 取正负符号(1表示正数，-1表示负数)
#define SIGN(num) (((num)>=0)?(1):(-1))
/// 整数4舍5入除法
#define IDIV45(a, b) (((a)+((b)>>1))/(b))
/// 浮点数4舍5入除法
#define FDIV45(a, b) ((a)*1.0/(b)+0.5)
/// 差值
#define DIFF(a, b) (((a)>(b))?((a)-(b)):((b)-(a)))

/// num1, num2 之前的误差是否小于 err
#define ISABOUT(num1, num2, err) 	((((num1)-(num2))>(err) || ((num1)-(num2))<(-(err)))?false:true)
/// num 是否在 [min, max] 之间
#define ISBETWEEN(num, min, max) 	(((num)>=(min) && ((num)<=(max)))?true:false)
/// num1 和 num2 相差多少(%)
#define ISTIMES(num1, num2) 		((num1>num2)?(num1*100L/num2):(num2*100L/num1))
/// num1 和 num2 误差是多少(%)
#define PERR(num1, num2)			(ISTIMES(num1, num2) - 100)

#define MIN(a, b) ((a)<(b)?(a):(b))
#define MAX(a, b) ((a)>(b)?(a):(b))

#define MIN3(a, b, c) MIN(MIN((a), (b)), (c))
#define MAX3(a, b, c) MAX(MAX((a), (b)), (c))

#define COUNT(v) (sizeof(v)/sizeof(v[0]))

#define IS_VALID_HEX_CHAR(ch) ( ((ch>='0') && (ch<='9')) || ((ch>='A') && (ch<='F')) || ((ch>='a') && (ch<='f')) )

#ifdef __cplusplus
#define NULLOP()    do {} while(0)
#else
#define NULLOP()    ((void *)0)
#endif

/// 避免未引用警告
#define UNUSED(x)	((void *)(x))

/// 多行语句宏定义
#define st(x)      do { x } while (__LINE__ == -1)

#define QUOTE(x) #x


/// 常用函数类型定义
typedef void (*FUNC_void_void)(void);
typedef void (*FUNC_void_u8)(uint8_t p1);
typedef void (*FUNC_void_u8p)(uint8_t *p1);
typedef void (*FUNC_void_u16)(uint16_t p1);
typedef void (*FUNC_void_u32)(uint32_t p1);
typedef void (*FUNC_void_voidp)(void* p1);
typedef void (*FUNC_void_u8_u32)(uint8_t p1, uint32_t p2);
typedef void (*FUNC_void_u8_u16)(uint8_t p1, uint16_t p2);
typedef void (*FUNC_void_u8_u8)(uint8_t p1, uint8_t p2);
typedef void (*FUNC_void_u32_u8)(uint32_t p1, uint8_t p2);
typedef void (*FUNC_void_u32_u8_u8)(uint32_t p1, uint8_t p2, uint8_t p3);
typedef void (*FUNC_void_u16_voidp)(uint16_t p2, void* p3);
typedef void (*FUNC_void_int_voidp)(int p2, void* p3);
typedef void (*FUNC_int_int_int)(int p1, int p2);
typedef void (*FUNC_void_int_int_voidp)(int p1, int p2, void* p3);
typedef void (*FUNC_void_u32_u16_voidp)(uint32_t p1, uint16_t p2, void* p3);
typedef void (*FUNC_void_u16_u16_voidp)(uint16_t p1, uint16_t p2, void* p3);
typedef void (*FUNC_void_u8_voidp)(uint8_t p1, void* p2);
typedef void (*FUNC_void_u8_u8_u16)(uint8_t p1, uint8_t p2, uint16_t p3);
typedef void (*FUNC_void_u8_u8_voidp)(uint8_t p1, uint8_t p2, void* p3);
typedef void (*FUNC_void_u16_u32)(uint16_t p1, uint32_t p2);
typedef void (*FUNC_void_u32_u16_u32)(uint32_t p1, uint16_t p2, uint32_t p3);
typedef uint8_t   (*FUNC_u8_void)(void);
typedef uint8_t   (*FUNC_u8_u8)(uint8_t p1);
typedef uint32_t  (*FUNC_u32_u8)(uint8_t p1);
typedef uint32_t  (*FUNC_u32_u32)(uint32_t p1);
typedef int  (*FUNC_int_void)();
typedef bool (*FUNC_bool_u32)(uint32_t p1);
typedef bool (*FUNC_bool_voidp)(void* p1);
typedef void (*FUNC_void_s8_voidp)(s8 p2, void* p3);
typedef void (*FUNC_void_s8_u16_voidp)(s8 p1, uint16_t p2, void* p3);
typedef void (*FUNC_void_u8_u8_u16_voidp)(uint8_t p1, uint8_t p2, uint16_t p3, void* p4);


#ifdef __cplusplus
}
#endif

#endif // __STD_TYPE_H__
